package com.sky.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Redis 配置类：完善序列化方式，避免取值为 null
 */
@Slf4j
//@Configuration（原配置类）
public class RedisConfigration {

    @Bean
    // 明确泛型：Key为String类型，Value为Object类型（支持Integer、对象等）
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {//Redis连接工厂
        log.info("初始化Redis配置");
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();//创建RedisTemplate对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);//设置Redis连接工厂

        // 1. 配置 Key 的序列化器：String 序列化（保证 Key 可读）
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer); // Key 序列化
        redisTemplate.setHashKeySerializer(stringSerializer); // Hash Key 序列化

        // 2. 配置 Value 的序列化器：JSON 序列化（支持复杂类型，避免 JDK 序列化的字节数组问题）
        Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);//创建JSON序列化器
        // 配置 Jackson 序列化规则（避免反序列化时丢失类型信息）
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//设置所有属性都可见
        // 启用默认的类型解析（存储时会额外保存类信息，反序列化更准确）
        objectMapper.activateDefaultTyping(//启用默认的类型解析
                objectMapper.getPolymorphicTypeValidator(),//获取多态类型验证器
                ObjectMapper.DefaultTyping.NON_FINAL//非最终类型
        );
        jsonSerializer.setObjectMapper(objectMapper);//设置JSON序列化器的对象映射器

        // 设置 Value 序列化器
        redisTemplate.setValueSerializer(jsonSerializer); // Value 序列化
        redisTemplate.setHashValueSerializer(jsonSerializer); // Hash Value 序列化

        // 初始化 RedisTemplate 配置
        redisTemplate.afterPropertiesSet();//初始化RedisTemplate配置
        return redisTemplate;//返回RedisTemplate对象
    }
}